Skip to content

Replace library/busybox with lighter container repo - #20671

Merged
pondrejk merged 1 commit into
SatelliteQE:masterfrom
lpramuk:replace_busybox_container_repo
Feb 24, 2026
Merged

Replace library/busybox with lighter container repo#20671
pondrejk merged 1 commit into
SatelliteQE:masterfrom
lpramuk:replace_busybox_container_repo

Conversation

@lpramuk

@lpramuk lpramuk commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

Problem Statement

Gradually over time the library/busybox repo is becoming more and more huge.
The problem with repo sync arises especially in IPv6 environment where the traffic goes over IPv6-to-4 proxy.

Testing revealed that syncing over IPv4 takes approx. 10 min while syncing over IPv6 takes 25 min and tends to time out quite often.

Solution

Find more suitable replacement for testing container repo target

Related Issues

SAT-41831

Summary by Sourcery

Update container test configuration to use a lighter upstream image and adjust test execution accordingly.

Enhancements:

  • Change the default container upstream image from library/busybox to jmalloc/echo-server in configuration validators.
  • Adjust container management CLI test to run the pulled image in detached mode and simplify container ID extraction from command output.

Tests:

  • Adapt the container pull-and-run test to work with the new upstream image behavior while maintaining container cleanup.

@lpramuk lpramuk self-assigned this Jan 21, 2026
@lpramuk lpramuk added CherryPick PR needs CherryPick to previous branches AutoMerge_Cherry_Picked The cherrypicked PRs of master PR would be automerged if all checks passing 6.16.z 6.17.z 6.18.z Introduced in or relating directly to Satellite 6.18 labels Jan 21, 2026
@lpramuk
lpramuk force-pushed the replace_busybox_container_repo branch 2 times, most recently from c0598a7 to 81b1e2a Compare January 29, 2026 11:15
@lpramuk
lpramuk force-pushed the replace_busybox_container_repo branch from 81b1e2a to b5835c0 Compare February 21, 2026 13:48
@lpramuk
lpramuk marked this pull request as ready for review February 21, 2026 13:48
@lpramuk
lpramuk requested review from a team as code owners February 21, 2026 13:48
@sourcery-ai

sourcery-ai Bot commented Feb 21, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Switches the default container test image repository from library/busybox to jmalloc/echo-server and adjusts the CLI container management test to run the image in detached mode and correctly parse the container ID from command output for cleanup.

Sequence diagram for updated container management test flow

sequenceDiagram
    actor Tester
    participant TestCase
    participant Config
    participant CLI
    participant ContainerRuntime
    participant Registry

    Tester->>TestCase: run test_container_management
    TestCase->>Config: get container.upstream_name
    Config-->>TestCase: jmalloc/echo-server (default)

    TestCase->>CLI: container run --detached jmalloc/echo-server
    CLI->>ContainerRuntime: create and start container (detached)
    ContainerRuntime->>Registry: pull jmalloc/echo-server
    Registry-->>ContainerRuntime: image layers
    ContainerRuntime-->>CLI: stdout with container_id
    CLI-->>TestCase: raw stdout

    TestCase->>TestCase: parse container_id from stdout

    TestCase->>CLI: container stop container_id
    CLI->>ContainerRuntime: stop container
    ContainerRuntime-->>CLI: stopped
    CLI-->>TestCase: success

    TestCase->>CLI: container rm container_id
    CLI->>ContainerRuntime: remove container
    ContainerRuntime-->>CLI: removed
    CLI-->>TestCase: success
    TestCase-->>Tester: test passed
Loading

Class diagram for container configuration validation changes

classDiagram
    class Validator {
        +string key
        +bool must_exist
        +type is_type_of
        +any default
    }

    class ContainerConfig {
        +string upstream_name
        +list~string~ alternative_upstream_names
    }

    class ConfigRegistry {
        +ContainerConfig container
        +get_value(key) any
        +set_value(key, value) void
    }

    ConfigRegistry o-- ContainerConfig : has
    ConfigRegistry ..> Validator : uses

    class UpstreamNameValidator {
        +string key = container.upstream_name
        +bool must_exist = true
        +type is_type_of = str
        +string default = jmalloc/echo-server
    }

    UpstreamNameValidator --|> Validator
Loading

Flow diagram for resolving default container image repository

flowchart TD
    A[Start test
read container config] --> B{container.upstream_name
configured?}
    B -- Yes --> C[Use configured
container.upstream_name]
    B -- No --> D[Apply default
jmalloc/echo-server]

    C --> E[Run container tests
using selected repo]
    D --> E[Run container tests
using selected repo]
    E --> F[Cleanup containers]
    F --> G[End]
Loading

File-Level Changes

Change Details Files
Update the default upstream container image used in tests to a lighter repository.
  • Change the default value of the container.upstream_name config validator from a busybox image to jmalloc/echo-server.
  • Keep existing validation behavior (must_exist, type checking) while only modifying the default image name.
robottelo/config/validators.py
Adjust container management CLI test to work with the new image semantics and fix container ID extraction.
  • Run the pulled container image in detached mode using docker run -d so that containers stay alive for inspection and cleanup.
  • Fix parsing of docker ps output by treating stdout as a string and splitting it directly, rather than indexing as if it were a list of lines.
  • Ensure stop and remove logic still runs in a finally block so containers are always cleaned up even on test failure.
tests/foreman/cli/test_container_management.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The change from result.stdout[0] to result.stdout.split()[0] assumes stdout is now a string rather than a list; please confirm and handle both cases (or enforce one type) to avoid type errors across different execute implementations.
  • Since docker run -d already prints the container ID, you can simplify the cleanup logic by capturing that ID directly from the docker run result instead of parsing docker ps -a | grep ..., which is more brittle and may misbehave if multiple containers match.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The change from `result.stdout[0]` to `result.stdout.split()[0]` assumes `stdout` is now a string rather than a list; please confirm and handle both cases (or enforce one type) to avoid type errors across different `execute` implementations.
- Since `docker run -d` already prints the container ID, you can simplify the cleanup logic by capturing that ID directly from the `docker run` result instead of parsing `docker ps -a | grep ...`, which is more brittle and may misbehave if multiple containers match.

## Individual Comments

### Comment 1
<location> `robottelo/config/validators.py:122` </location>
<code_context>
             must_exist=True,
             is_type_of=str,
-            default='library/busybox',
+            default='jmalloc/echo-server',
         ),
         Validator(
</code_context>

<issue_to_address>
**🚨 issue (security):** Consider pinning the container image to a specific tag instead of relying on an unversioned default.

This change shifts the default from an official image to a third‑party one and leaves the tag effectively unpinned (likely `latest`), which can introduce non-deterministic behavior and security/behavior drift as the upstream image changes. If this default is intended to be stable and reproducible, please pin a specific tag (e.g. `jmalloc/echo-server:<version>`) or clearly document that an unpinned, flexible image is expected here.
</issue_to_address>

### Comment 2
<location> `tests/foreman/cli/test_container_management.py:106` </location>
<code_context>
                     f'docker ps -a | grep {repo["published-at"]}'
                 )
-                container_id = result.stdout[0].split()[0]
+                container_id = result.stdout.split()[0]
                 module_container_contenthost.execute(f'docker stop {container_id}')
                 module_container_contenthost.execute(f'docker rm {container_id}')
</code_context>

<issue_to_address>
**issue:** Guard against empty `stdout` before splitting to avoid errors in cleanup

The previous version indexed `stdout[0]` assuming a list; now we call `stdout.split()[0]` assuming a non-empty string. If `docker ps -a | grep {repo["published-at"]}` matches nothing, `stdout` can be empty and `stdout.split()[0]` will raise `IndexError`, obscuring the real issue. Please either assert `result.status == 0` and that `result.stdout.strip()` is non-empty before splitting, or explicitly handle the "no container found" case and fail the test with a clear message.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread robottelo/config/validators.py
Comment thread tests/foreman/cli/test_container_management.py Outdated

@chris1984 chris1984 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the testing times with jmalloc/echo-server compared to library/busybox? Is there anything we are losing by switching other than getting shorter sync times?

@vsedmik

vsedmik commented Feb 23, 2026

Copy link
Copy Markdown
Contributor

What are the testing times with jmalloc/echo-server compared to library/busybox? Is there anything we are losing by switching other than getting shorter sync times?

We are loosing some "Schema Version 1" manifests, which jmalloc/echo-server does not contain.
But I also tend to leave library/busybox, we sometimes get "Too many requests" from gcr.io for that repo.

@lpramuk, are you aware of any similar-sized repo with V1 + V2 manifests?

@lpramuk
lpramuk force-pushed the replace_busybox_container_repo branch from b5835c0 to c56deec Compare February 23, 2026 14:10
@lpramuk

lpramuk commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author

What are the testing times with jmalloc/echo-server compared to library/busybox? Is there anything we are losing by switching other than getting shorter sync times?

@chris1984 I tested a test collection of all affected tests, (totaling to 107 tests):

library/busybox IPv4 master
https://jenkins-csb-satellite-qe-satqe.dno.corp.redhat.com/job/robottelo-pr-testing/14109/
======== 107 passed, 18 deselected, 1207 warnings in 8918.45s (2:28:38) ========

library/busybox IPv6 master
https://jenkins-csb-satellite-qe-satqe.dno.corp.redhat.com/job/robottelo-pr-testing/14116/
======== 107 passed, 18 deselected, 1215 warnings in 9036.00s (2:30:35) ========

jmalloc/echo-server IPv4 master
https://jenkins-csb-satellite-qe-satqe.dno.corp.redhat.com/job/robottelo-pr-testing/14119/
======== 107 passed, 18 deselected, 958 warnings in 4416.91s (1:13:36) =========

jmalloc/echo-server IPv6 master
https://jenkins-csb-satellite-qe-satqe.dno.corp.redhat.com/job/robottelo-pr-testing/14123/
======== 107 passed, 18 deselected, 983 warnings in 4678.68s (1:17:58) =========

You can see that total execution time dropped to 50% by 1hr 15min.
However, the most important is achieved stability. We no longer sync external 0,27 GBs multiple times (per each test/module)

@lpramuk

lpramuk commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author

@vsedmik What about keeping busybox just for content testing where V1 + V2 manifests matter and everywhere else just use echo-server

@vsedmik

vsedmik commented Feb 23, 2026

Copy link
Copy Markdown
Contributor

@vsedmik What about keeping busybox just for content testing where V1 + V2 manifests matter and everywhere else just use echo-server

I'm good with that. 👍

@lpramuk

lpramuk commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: >-
  -v
  tests/foreman/api/test_capsulecontent.py::TestCapsuleContentManagement::test_positive_content_counts_for_mixed_cv
  tests/foreman/api/test_docker.py::TestDockerRepository
  tests/foreman/api/test_http_proxy.py::test_positive_end_to_end[module_repos_collection_with_manifest0-unauth_http_proxy-hostname]
  tests/foreman/api/test_product.py::test_positive_sync_several_repos
  tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_create
  tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_delete_product_with_synced_repo
  tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_synchronize_docker_repo_with_included_tags
  tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_manifests_lists_in_docker_tags
  tests/foreman/api/test_repository.py::TestDockerRepository::test_negative_synchronize_docker_repo_with_mix_valid_invalid_tags
  tests/foreman/api/test_repository.py::TestDockerRepository::test_negative_synchronize_docker_repo_with_invalid_tags
  tests/foreman/cli/test_capsulecontent.py::test_positive_repair_artifacts
  tests/foreman/cli/test_capsulecontent.py::test_positive_content_counts_for_mixed_cv
  tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_pull_image
  tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_container_admin_end_to_end_search
  tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_container_admin_end_to_end_pull
  tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_pull_content_with_longer_name
  tests/foreman/cli/test_contentview.py::TestContentView::test_positive_remove_cv_version_from_multi_env
  tests/foreman/cli/test_contentview.py::TestContentViewFileRepo::test_promote_ccv_to_lce_with_nondefault_pattern
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_with_name
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_repos_using_same_product
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_repos_using_multiple_products
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_sync
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_delete_random_repo_by_id
  tests/foreman/cli/test_docker.py::TestDockerRepository::test_negative_docker_upload_content
  tests/foreman/cli/test_docker.py::TestDockerContentView::test_positive_add_docker_repos_by_id
  tests/foreman/cli/test_pulp.py
  tests/foreman/cli/test_repository.py::TestRepository::test_positive_create_docker_repo_with_upstream_name
  tests/foreman/cli/test_repository.py::TestRepository::test_positive_create_docker_repo_with_name
  tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo
  tests/foreman/cli/test_repository.py::TestRepository::test_verify_checksum_container_repo
  tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo_set_tags_later_additive
  tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo_set_tags_later_content_only
  tests/foreman/cli/test_repository.py::TestRepository::test_negative_synchronize_docker_repo_with_mix_valid_invalid_tags
  tests/foreman/cli/test_satellitesync.py::TestRepositoryExport::test_positive_export_repository_docker
  tests/foreman/cli/test_satellitesync.py::TestRepositoryExport::test_positive_export_version_docker
  tests/foreman/ui/test_containerimagetag.py::test_positive_search
network_type: ipv6

@lpramuk lpramuk added the 6.19.z label Feb 23, 2026
@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 14417
Build Status: SUCCESS
PRT Comment: pytest -v tests/foreman/api/test_capsulecontent.py::TestCapsuleContentManagement::test_positive_content_counts_for_mixed_cv tests/foreman/api/test_docker.py::TestDockerRepository tests/foreman/api/test_http_proxy.py::test_positive_end_to_end[module_repos_collection_with_manifest0-unauth_http_proxy-hostname] tests/foreman/api/test_product.py::test_positive_sync_several_repos tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_create tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_delete_product_with_synced_repo tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_synchronize_docker_repo_with_included_tags tests/foreman/api/test_repository.py::TestDockerRepository::test_positive_manifests_lists_in_docker_tags tests/foreman/api/test_repository.py::TestDockerRepository::test_negative_synchronize_docker_repo_with_mix_valid_invalid_tags tests/foreman/api/test_repository.py::TestDockerRepository::test_negative_synchronize_docker_repo_with_invalid_tags tests/foreman/cli/test_capsulecontent.py::test_positive_repair_artifacts tests/foreman/cli/test_capsulecontent.py::test_positive_content_counts_for_mixed_cv tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_pull_image tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_container_admin_end_to_end_search tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_container_admin_end_to_end_pull tests/foreman/cli/test_container_management.py::TestDockerClient::test_positive_pull_content_with_longer_name tests/foreman/cli/test_contentview.py::TestContentView::test_positive_remove_cv_version_from_multi_env tests/foreman/cli/test_contentview.py::TestContentViewFileRepo::test_promote_ccv_to_lce_with_nondefault_pattern tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_with_name tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_repos_using_same_product tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_create_repos_using_multiple_products tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_sync tests/foreman/cli/test_docker.py::TestDockerRepository::test_positive_delete_random_repo_by_id tests/foreman/cli/test_docker.py::TestDockerRepository::test_negative_docker_upload_content tests/foreman/cli/test_docker.py::TestDockerContentView::test_positive_add_docker_repos_by_id tests/foreman/cli/test_pulp.py tests/foreman/cli/test_repository.py::TestRepository::test_positive_create_docker_repo_with_upstream_name tests/foreman/cli/test_repository.py::TestRepository::test_positive_create_docker_repo_with_name tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo tests/foreman/cli/test_repository.py::TestRepository::test_verify_checksum_container_repo tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo_set_tags_later_additive tests/foreman/cli/test_repository.py::TestRepository::test_positive_synchronize_docker_repo_set_tags_later_content_only tests/foreman/cli/test_repository.py::TestRepository::test_negative_synchronize_docker_repo_with_mix_valid_invalid_tags tests/foreman/cli/test_satellitesync.py::TestRepositoryExport::test_positive_export_repository_docker tests/foreman/cli/test_satellitesync.py::TestRepositoryExport::test_positive_export_version_docker tests/foreman/ui/test_containerimagetag.py::test_positive_search --external-logging
Test Result : =============== 126 passed, 1023 warnings in 4742.09s (1:19:02) ================

@Satellite-QE Satellite-QE added the PRT-Passed Indicates that latest PRT run is passed for the PR label Feb 23, 2026
@pondrejk
pondrejk merged commit 8ac73bc into SatelliteQE:master Feb 24, 2026
12 checks passed
github-actions Bot pushed a commit that referenced this pull request Feb 24, 2026
github-actions Bot pushed a commit that referenced this pull request Feb 24, 2026
lpramuk added a commit to lpramuk/robottelo that referenced this pull request Feb 24, 2026
lpramuk added a commit to lpramuk/robottelo that referenced this pull request Feb 24, 2026
lpramuk added a commit that referenced this pull request Feb 25, 2026
Replace library/busybox with lighter container repo (#20671)

(cherry picked from commit 8ac73bc)
lpramuk added a commit that referenced this pull request Feb 25, 2026
Replace library/busybox with lighter container repo (#20671)

(cherry picked from commit 8ac73bc)
lpramuk added a commit that referenced this pull request Feb 25, 2026
Replace library/busybox with lighter container repo (#20671)

(cherry picked from commit 8ac73bc)

Co-authored-by: Lukas Pramuk <lpramuk@redhat.com>
rmynar pushed a commit to rmynar/robottelo that referenced this pull request Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.16.z 6.17.z 6.18.z Introduced in or relating directly to Satellite 6.18 6.19.z AutoMerge_Cherry_Picked The cherrypicked PRs of master PR would be automerged if all checks passing CherryPick PR needs CherryPick to previous branches PRT-Passed Indicates that latest PRT run is passed for the PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants